package gt

import (
	"time"

	"gitee.com/dark.H/gs"
)

type Panel struct {
	loc *PanelLoc

	Height int
	Width  int
}

func NewPanel() *Panel {
	height, width := gs.GetWindowsSize()
	height += 1
	p := &Panel{
		loc: &PanelLoc{
			X:          1,
			Y:          1,
			ShowBar:    true,
			ShowBorder: true,
			HideCursor: true,
		},
		Height: height,
		Width:  width,
	}

	return p
}

func (p *Panel) Copy() (np *Panel) {
	np = &Panel{
		loc:    p.loc.Copy(),
		Height: p.Height,
		Width:  p.Width,
	}
	return np
}

func (p *Panel) SetTitle(title gs.Str) *Panel {
	p.loc.TItle = title
	return p
}

func (lph *Panel) LogInfo(fpath string) {
	x, y := lph.Loc()
	h, w := lph.OuterSize()
	mh, mw := gs.GetWindowsSize()
	gs.Str("x:%d y:%d w:%d h:%d  winline:%d winwidth:%d \n").F(x, y, w, h, mh, mw).ToFile(fpath)
}

func (p *Panel) GetTitle() gs.Str {
	return p.loc.TItle
}

func (p *Panel) SetLoc(x, y int, wrap ...bool) *Panel {
	// gs.Str("wantloc x:%d, y:%d width : %d height : %d\n").F(x, y).ToFile("/tmp/ss.txt")
	if wrap != nil && wrap[0] {
		wy, wx := gs.GetWindowsSize()
		// gs.Str("1 x:%d, y:%d width : %d\n").F(x, y, p.Width).ToFile("/tmp/some.txt")
		if wx-p.Width-x < 0 {
			x = wx - p.Width - 2
		}
		if wy-p.Height-y < 0 {
			y = wy - p.Height
		}
		if x < 1 {
			x = 1
		}
		if y < 1 {
			y = 1
		}
		// gs.Str("set loc x:%d, y:%d width : %d height : %d\n").F(x, y, p.Width, p.Height).ToFile("/tmp/ss.txt")
	}
	p.loc.X = x
	p.loc.Y = y
	return p
}

func (p *Panel) Loc() (x, y int) {
	x = p.loc.X
	y = p.loc.Y
	return
}

func (p *Panel) ContentLoc() (x, y int) {
	x, y = p.Loc()
	if p.loc.ShowBorder {
		x += 1
		y += 1
	}
	return
}

func (p *Panel) LocY() (y int) {

	y = p.loc.Y
	return
}

func (p *Panel) LocX() (x int) {
	x = p.loc.X
	return
}

func (p *Panel) SetBar(ifshow bool) *Panel {
	p.loc.ShowBar = ifshow
	return p
}

func (p *Panel) SetBorder(ifshow bool) *Panel {
	p.loc.ShowBorder = ifshow
	if !p.loc.ShowBorder {
		if p.Height > 2 {
			p.Height -= 2
		}
	}
	return p
}

func (p *Panel) SetSize(width, heiht int) *Panel {
	p.Width = width
	p.Height = heiht
	return p
}

func (p *Panel) OuterSize() (width, height int) {

	width = p.Width
	height = p.Height

	return
}

func (p *Panel) InnerSize() (width, height int) {
	if p.loc.ShowBorder {
		width = p.Width - 2
		height = p.Height - 2
	} else {
		width = p.Width
		height = p.Height

	}
	return
}

func (p *Panel) SetIfShowCursor(show bool) *Panel {
	if show {
		// gs.Str("").ANSIShowCursor().Print()
		p.loc.HideCursor = false
	} else {
		// gs.Str("").ANSIHideCursor().Print()
		p.loc.HideCursor = true
	}
	return p
}

func (p *Panel) SetCursorLoc(x, y int) *Panel {
	gs.Str("").ANSICursor(y, x).Print()
	return p
}

func (p *Panel) SetSizeWidth(width int) *Panel {
	p.Width = width
	return p
}

func (p *Panel) SetSizeHeight(height int) *Panel {
	if p.loc.ShowBorder {
		p.Height = height + 2
	} else {
		p.Height = height
	}
	return p
}

func (p *Panel) Wait(milisec ...int) *Panel {
	if milisec != nil {
		time.Sleep(time.Duration(milisec[0]) * time.Millisecond)
	} else {
		time.Sleep(500 * time.Millisecond)
	}
	return p
}

func (p *Panel) DrawBuf(buf gs.Str, selectedNo ...int) *Panel {
	p.loc.ClearInArea(p.Height, p.Width)
	p.loc.PrintInArea(buf, p.Height, p.Width, selectedNo...)
	return p
}

func (p *Panel) Clear(spech ...rune) *Panel {
	h, w := p.Height, p.Width
	if spech != nil {
		p.loc.ClearInArea(h, w, spech...)
	} else {
		p.loc.ClearInArea(h, w)
	}

	return p
}

func (p *Panel) ClearArea(x, y, width, height int, spe ...rune) *Panel {
	p2 := p.Copy()
	p2.loc.X = x
	p2.loc.Y = y
	p2.Width = width
	p2.Height = height
	p2.Clear()
	return p
}

func (p *Panel) ClearAll() *Panel {
	p2 := p.Copy()
	height, width := gs.GetWindowsSize()
	p2.loc.X = 1
	p2.loc.Y = 1
	p2.Width = width
	p2.Height = height
	p2.Clear()
	return p
}

func (p *Panel) SetPos(x, y int) *Panel {
	return p.SetPosX(x).SetPosY(y)
}

func (p *Panel) Pos() (x int, y int) {
	x = p.loc.Xpos
	y = p.loc.Ypos
	return
}

func (p *Panel) SetPosX(x int) *Panel {
	p.loc.Xpos = x

	// if p.loc.Xpos >= p.Width {
	// 	p.loc.Xpos = p.loc.Xpos % p.Width
	// }

	return p
}

func (p *Panel) SetPosY(y int) *Panel {
	p.loc.Ypos = y

	return p
}

type Point struct {
	X, Y int
}

func (p *Panel) Rect() (leftTop, rightTop, leftBottom, rightBottom Point) {
	leftTop = Point{p.loc.X, p.loc.Y}
	leftBottom = Point{p.loc.X, p.loc.Y + p.Height}

	rightTop = Point{p.loc.X + p.Width, p.loc.Y}
	rightBottom = Point{p.loc.X + p.Width, p.loc.Y + p.Height}
	return
}

func (p *Panel) In(point Point) bool {
	if p.loc.X < point.X && point.X < p.loc.X+p.Width {
		if p.loc.Y < point.Y && point.Y < p.loc.Y+p.Height {
			return true
		}
	}
	return false
}
